package top.xmindguoguo.utils;

import com.sun.image.codec.jpeg.JPEGCodec;
import com.sun.image.codec.jpeg.JPEGImageEncoder;

import javax.imageio.ImageIO;
import java.awt.*;
import java.awt.geom.Ellipse2D;
import java.awt.image.BufferedImage;
import java.io.*;

public class ImageUtils {
    // 初始化当前类
    private static ImageUtils imageUtils = new ImageUtils();
    // Image 工具类
    private Graphics2D graphics2D = null;
    // 原始图片
    private BufferedImage bufferedImage = null;

    /**
     * 懒汉单例模式
     * @return
     */
    public static ImageUtils getInstance(){
        return imageUtils;
    }

    /**
     *  基础图片初始化，传入作为背景图片的的路径
     * @param imageUrl
     * @return
     * @throws IOException
     */
    public Graphics2D getGraphics2DBaseImage(String imageUrl) throws IOException {
        InputStream inputStream = new FileInputStream(imageUrl);
        bufferedImage = ImageIO.read(inputStream);
        if (inputStream != null) {
            inputStream.close();
            graphics2D = bufferedImage.createGraphics();

        }
        return graphics2D;
    }


    /**
     * 在图片中添加文字内容
     * @param content
     * @param color
     * @param font
     * @param x
     * @param y
     */
    public void  setString(String content, Color color, Font font, Integer x, Integer y){
        // 图片的默认设置
        graphics2D.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
        // 设置字体的颜色
        graphics2D.setColor(color);
        // 设置字体、字体大小、字体效果（倾斜，底线等）
        graphics2D.setFont(font);
        // 设置字体显示的内容和位置
        graphics2D.drawString(content, x, y);
    }

    /**
     * 处理要合并的图片,支持图片椭圆行处理
     * @param imageUrl
     * @param x
     * @param y
     * @param isEllipse
     * @throws IOException
     */
    public void setImageLocalShape(String imageUrl, Integer x, Integer y, boolean isEllipse)throws IOException{
        // 需要处理的图片
        InputStream inputStreamIcon = new FileInputStream(imageUrl);
        BufferedImage bufferedImageIcon = ImageIO.read(inputStreamIcon);
        if (inputStreamIcon != null) {
            inputStreamIcon.close();
        }
        // 判断是否作椭圆处理
        if(isEllipse) {
            /**
             * 在处理合并图片形状时，一定要重新获取下原始图片的Graphics2D类，否则，会出现
             * 多个图片情况下只能有一个图片合并成功，其他图片不显示的情况
             * 原因: 实例引用覆盖导致的。调用clip()方法会将原先的图片覆盖导致只处理当前图片的情况
             */
            Graphics2D graphics2DEll = bufferedImage.createGraphics();
            // 将图片处理为圆形
            Ellipse2D.Double shape = new Ellipse2D.Double(x, y, bufferedImageIcon.getWidth(), bufferedImageIcon.getHeight());
            graphics2DEll.clip(shape);
            graphics2DEll.drawImage(bufferedImageIcon, x, y, null);
        }else {
            graphics2D.drawImage(bufferedImageIcon, x, y, null);
        }

    }

    /**
     * 处理图片的位置和大小图形
     * @param imageUrl
     * @param x
     * @param y
     * @param width
     * @param height
     * @param isEllipse
     * @throws IOException
     */
    public void setImageLocalShapeSize(String imageUrl, Integer x, Integer y, Integer width, Integer height, boolean isEllipse)throws IOException{
        // 需要处理的图片
        InputStream inputStreamIcon = new FileInputStream(imageUrl);
        BufferedImage bufferedImageIcon = ImageIO.read(inputStreamIcon);
        if (inputStreamIcon != null) {
            inputStreamIcon.close();
        }
        // 判断是否作椭圆处理
        if(isEllipse) {
            /**
             * 在处理合并图片形状时，一定要重新获取下原始图片的Graphics2D类，否则，会出现
             * 多个图片情况下只能有一个图片合并成功，其他图片不显示的情况
             * 原因: 实例引用覆盖导致的。调用clip()方法会将原先的图片覆盖导致只处理当前图片的情况
             */
            Graphics2D graphics2DEll = bufferedImage.createGraphics();
            // 将图片处理为圆形
            Ellipse2D.Double shape = new Ellipse2D.Double(x, y, bufferedImageIcon.getWidth(), bufferedImageIcon.getHeight());
            graphics2DEll.clip(shape);
            graphics2DEll.drawImage(bufferedImageIcon, x, y, width, height, null);
        }else {
            graphics2D.drawImage(bufferedImageIcon, x, y, width, height, null);
        }


    }

    /**
     *  目标图片生成
     * @param imageUrl
     * @throws IOException
     */
    public void  targetImage(String imageUrl) throws IOException{
        // 初始化目标图片的路径
        OutputStream outputStream = new FileOutputStream(imageUrl);
        // 生成图片
        JPEGImageEncoder enc = JPEGCodec.createJPEGEncoder(outputStream);
        // 将生成图片中添加的信息处理
        enc.encode(bufferedImage);
        // 释放合并图片占用的资源信息
        graphics2D.dispose();
    }

    public static  void main(String[] args){
        // 获取工具类实例
        ImageUtils imageUtils = ImageUtils.getInstance();
        try {
            // 设置背景图片
            imageUtils.getGraphics2DBaseImage("F:\\tmp\\yqxr_back.jpg");
            // 设置字体
            Color color=new Color(152,99,59);
            Font font = new Font("微软雅黑", Font.PLAIN, 20);// 添加字体的属性设置
            String str = "我对你的爱是真的。";

            imageUtils.setString(str,color,font,175,790);

            // 设置头像
            imageUtils.setImageLocalShapeSize("F:\\tmp\\pic.png",310, 635,120,120,true);
            // 二维码
            imageUtils.setImageLocalShapeSize("F:\\tmp\\timg.jpg",230, 810,305,307,false);
            // 图标
            imageUtils.setImageLocalShape("F:\\tmp\\icon.png",340, 920,false);
            // 生成图片
            imageUtils.targetImage("F:\\tmp\\target100.jpg");
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

}
